package com.novax.ex.activity.provider.service;

import com.alibaba.fastjson.JSON;
import com.novax.ex.activity.infrastructure.entity.MallOrderWinner;
import com.novax.ex.activity.infrastructure.entity.MallPrize;
import com.novax.ex.activity.infrastructure.entity.MallPrizeLottery;
import com.novax.ex.activity.infrastructure.entity.MallPrizeOrder;
import com.novax.ex.activity.infrastructure.mapper.MallOrderWinnerMapper;
import com.novax.ex.activity.infrastructure.mapper.MallPrizeLotteryMapper;
import com.novax.ex.activity.infrastructure.mapper.MallPrizeMapper;
import com.novax.ex.activity.provider.handler.provider.MallOrderProvider;
import com.novax.ex.common.base.BaseEntity;
import com.novax.ex.common.base.BaseMapper;
import com.novax.ex.common.base.BaseService;
import com.novax.ex.common.core.redis.RedisDistributedLocker;
import com.novax.ex.common.core.redis.RedisLockUtil;
import com.novax.ex.common.enums.MallOrderWinnerStatus;
import com.novax.ex.common.enums.MallPrizeStatus;
import com.novax.ex.common.exception.BusinessException;
import com.novax.ex.common.util.CopyUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import jakarta.annotation.Resource;
import java.util.*;

/**
 * @Description 参与抽奖奖池表Service
 * @Author zhaolei
 * @Date 2/21/23 5:39 PM
 * @Version 1.0
 */
@Service
@Slf4j
public class MallPrizeLotteryService extends BaseService {
    @Resource
    private MallPrizeLotteryMapper mallPrizeLotteryMapper;
    @Resource
    private MallPrizeMapper mallPrizeMapper;
    @Resource
    private RedisDistributedLocker redisLocker;
    @Resource
    private MallOrderWinnerMapper mallOrderWinnerMapper;


    @Override
    protected BaseMapper getBaseMapper() {
        return mallPrizeLotteryMapper;
    }

    @Transactional
    public MallPrizeLottery buySuccess(MallPrizeOrder order) {
        //批量插入参与抽奖奖池表
        List<MallPrizeLottery> list = new ArrayList<>();
        MallPrizeLottery lottery = new MallPrizeLottery();
        lottery.setMallPrizeOrderId(order.getId());
        lottery.setUserId(order.getUserId());
        lottery.setMallPrizeId(order.getMallPrizeId());
        lottery.setMallProductId(order.getMallProductId());
        lottery.setStatus(1);
        for (int i = 0; i < order.getBuyCount(); i++) {
            list.add(lottery);
        }
        mallPrizeLotteryMapper.batchInsert(list);
        return startLottery(order.getMallPrizeId());
    }

    /**
     * @description: 抽奖逻辑
     * @author: Wade
     * @date: 3/28/23 5:08 PM
     * @param: [mallPrizeId]
     * @return: com.novax.ex.activity.infrastructure.entity.MallPrizeLottery
     **/
    public MallPrizeLottery startLottery(Long mallPrizeId) {
        MallPrize mallPrize = mallPrizeMapper.selectByPrimaryKey(mallPrizeId);
        if (Objects.nonNull(mallPrize) && mallPrize.getStatus().equals(MallPrizeStatus.over.getStatus())) {
            //加锁防止并发开奖给多个中奖者记录
            String lotteryLockKey = RedisLockUtil.LOTTERY_LOCK + mallPrizeId;
            boolean lotteryLock = redisLocker.tryLock(lotteryLockKey, false);// 给抽奖加锁
            try {
                if (lotteryLock) {
                    //判断中奖记录中是否存在记录，如果存在记录说明开过奖了，直接返回null
                    Map<String, Object> map = new HashMap<>();
                    map.put("mallPrizeId", mallPrizeId);
                    List<MallOrderWinner> winners = mallOrderWinnerMapper.selectList(map);
                    if (!CollectionUtils.isEmpty(winners)) {
                        return null;
                    }
                    //是结束状态，说明支付这笔钱的时候满足了金额达标了，需要进行抽奖抽奖成功后发抽奖成功消息
                    MallPrizeLottery mallPrizeLottery = mallPrizeLotteryMapper.lottery(mallPrize.getId(), mallPrize.getWinnerUserId());
                    //修改为中奖状态
                    MallPrizeLottery nlottery = new MallPrizeLottery();
                    nlottery.setId(mallPrizeLottery.getId());
                    nlottery.setStatus(2);
                    mallPrizeLotteryMapper.updateByPrimaryKeySelective(nlottery);
                    //返回此对象用于发消息出去
                    return mallPrizeLottery;
                }
            } catch (Exception e) {
                e.printStackTrace();
                log.error("一元购抽奖失败:mallPrizeId" + mallPrizeId);
                throw new BusinessException("mall start lottery invalid");
            } finally {
                redisLocker.unlock(lotteryLockKey);
            }
        }
        return null;
    }

}
